namespace SimpleWebServices.Web.UI.Html.Validation
{
    using System;
    using SimpleWebServices;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web.UI.Html.Elements;
    using Xunit;

    public sealed class StandardCheckBoxValidatorFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<StandardCheckBoxValidator>()
                .DerivesFrom<Validator>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new StandardCheckBoxValidator());
        }

        [Fact]
        public void ctor_IInnerElements_bool()
        {
            Assert.NotNull(new StandardCheckBoxValidator(new Label(), true));
        }

        [Fact]
        public void ctor_IInnerElementsNull_bool()
        {
            Assert.NotNull(new StandardCheckBoxValidator(null as IInnerElements, true));
        }

        [Fact]
        public void op_Configure_Form_DataCollection()
        {
            DataCollection data = new DataCollection();
            data.Add("Display", "display");
            data.Add("ErrorText", "error");
            data.Add("IsChecked", "true");

            Label label = new Label { Id = "display" };
            Form form = new Form
            {
                Elements = { label }
            };

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(null, null);
            obj.Configure(form, data);

            Assert.Same(label, obj.Display);
            Assert.Equal<string>("error", obj.ErrorText);
            Assert.True(obj.IsChecked.Value);
        }

        [Fact]
        public void op_Configure_Form_DataCollectionEmpty()
        {
            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(null, null);
            obj.Configure(new Form(), new DataCollection());

            Assert.Null(obj.Display);
            Assert.Null(obj.IsChecked);
        }

        [Fact]
        public void op_Configure_Form_DataCollectionNull()
        {
            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(null, null);
            obj.Configure(new Form(), null as DataCollection);

            Assert.Null(obj.Display);
            Assert.Null(obj.IsChecked);
        }

        [Fact]
        public void op_Validate_IElementNotIControl()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new StandardCheckBoxValidator().Validate(new Anchor()));
        }

        [Fact]
        public void op_Validate_IElementNotCheckBox()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new StandardCheckBoxValidator().Validate(new TextInput()));
        }

        [Fact]
        public void op_Validate_IElementNull()
        {
            Assert.Throws<ArgumentNullException>(() => new StandardCheckBoxValidator().Validate(null));
        }

        [Fact]
        public void op_Validate_IElementValidAny()
        {
            CheckBoxInput element = "<input type='checkbox' />".Deserialize<CheckBoxInput>();

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(new Label(), null);

            Assert.True(obj.Validate(element));
            Assert.Equal<int>(0, obj.Errors.Count);

            element.Checked = !element.Checked;

            Assert.True(obj.Validate(element));
            Assert.Equal<int>(0, obj.Errors.Count);
        }

        [Fact]
        public void op_Validate_IElementValidChecked()
        {
            CheckBoxInput element = "<input type='checkbox' checked='checked' />".Deserialize<CheckBoxInput>();

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(new Label(), true);

            Assert.True(obj.Validate(element));

            Assert.Equal<int>(0, obj.Errors.Count);
        }

        [Fact]
        public void op_Validate_IElementValidUnchecked()
        {
            CheckBoxInput element = "<input type='checkbox' />".Deserialize<CheckBoxInput>();

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(new Label(), false);

            Assert.True(obj.Validate(element));

            Assert.Equal<int>(0, obj.Errors.Count);
        }

        [Fact]
        public void op_Validate_IElementInvalidChecked()
        {
            string error = "Error text";

            CheckBoxInput element = "<input type='checkbox' checked='checked' />".Deserialize<CheckBoxInput>();

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(new Label(), false)
            {
                ErrorText = error
            };

            Assert.False(obj.Validate(element));

            Assert.Equal<int>(1, obj.Errors.Count);
            Assert.Equal<string>(error, obj.Errors[0].Description);
        }

        [Fact]
        public void op_Validate_IElementInvalidUnchecked()
        {
            string error = "Error text";

            CheckBoxInput element = "<input type='checkbox' />".Deserialize<CheckBoxInput>();

            StandardCheckBoxValidator obj = new StandardCheckBoxValidator(new Label(), true)
            {
                ErrorText = error
            };

            Assert.False(obj.Validate(element));

            Assert.Equal<int>(1, obj.Errors.Count);
            Assert.Equal<string>(error, obj.Errors[0].Description);
        }
    }
}